package com.kxz.ws;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kxz.pojo.Message;
import com.kxz.util.MessageUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/wss",configurator = GetHttpSessionConfig.class)
@Component
public class WebSocketServer {  //webSocket服务器端

    private static Map<String,WebSocketServer> alineUser=new ConcurrentHashMap<>();//concurrent包的线程安全Map，用来存放每个客户端对应的WebSocketService对象

    private Session session;            //与某个客户端的连接会话，需要通过它来给客户端发送数据,该对象可以发送消息给指定用户

    private HttpSession httpSession;    //HttpSession对象

    /**
     * 连接成功后服务器端要完成的操作
     * @param session
     * @param config
     * @throws IOException
     */
    @OnOpen
    public void onOpen(Session session,EndpointConfig config) throws IOException {  //广播所有用户名

        this.session=session;

        httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); //获取httpsession对象

        String uname= (String) httpSession.getAttribute("uname");   //从httpsession对象中获取用户名

        alineUser.put(uname,this);      //1、将当前对象存储到容器中
        //2、将当前在线用户的用户名推送给所有的客户端。
        //2-1获取消息，获取map集合中的key值，即所有的用户名
        String message=MessageUtils.getMessage(true,null,getNames());
        //2-2调用方法进行系统消息推送
        broadcastAllUsers(message);
//        System.out.println("连接成功");
    }
    //获取map集合中的key值
    public Set<String> getNames(){
        return alineUser.keySet();
    }
    public void broadcastAllUsers(String message) throws IOException {  //将该消息推送给所有的客户端
        Set<String> names=alineUser.keySet();
        for (String name:names){
            WebSocketServer ws=alineUser.get(name);
            ws.session.getBasicRemote().sendText(message);  //发给指定用户
        }
    }

    /**
     * 关闭连接后服务器要完成的操作
     * @param session
     */

    @OnClose
    public void onClose(Session session){
        System.out.println("连接关闭");
    }

    /**
     * 接收消息
     * @param
     * @return
     */
    @OnMessage
    public void onMsg(String message,Session session) throws IOException {  //接手某个用户的消息后转发给另一个用户
        //将message转换成Message对象
        ObjectMapper mapper=new ObjectMapper();
        Message mess=mapper.readValue(message,Message.class);
        //获取当前登录的用户
        String uname= (String) httpSession.getAttribute("uname");

        String toName=mess.getToName();     //获取接收消息的用户（message：toName,message）

        String data=mess.getMessage();      //获取消息数据

        String resultMessage=MessageUtils.getMessage(false,uname,data); //获取推送给指定用户的消息格式的数据
        //发送数据
        alineUser.get(toName).session.getBasicRemote().sendText(resultMessage);
//        return "servet 发送："+message;
    }

    /**
     * 发生错误时
     * @param session
     * @param tw
     */
    @OnError
    public void onError(Session session,Throwable tw){
        System.out.println("发生错误");
    }
}
